home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJSRC111.ZIP / utils / oread.c < prev    next >
C/C++ Source or Header  |  1993-11-12  |  3KB  |  154 lines

  1. #include <alloc.h>
  2. #include <dos.h>
  3. #include <stdio.h>
  4. #include <bios.h>
  5. #include <fcntl.h>
  6.  
  7. #define D_READ    2
  8. #define    D_WRITE    3
  9.  
  10. #define CACHE_SECTORS 18
  11.  
  12. typedef struct {
  13.   int fd; /* or drive, if cm set */
  14.   int cm, hm, sm;
  15.   long file_ptr;
  16.   void *cache;
  17.   long cache_fptr;
  18.   long cache_fptre;
  19.   int volume_in_drive;
  20. } oread;
  21.  
  22. void *oread_open(char *fn)
  23. {
  24.   oread *or;
  25.   if ((strlen(fn) == 2) && (fn[1] == ':'))
  26.   {
  27.     struct REGPACK r;
  28.     char buf[512];
  29.     int status;
  30.  
  31.     switch (fn[0])
  32.     {
  33.       case 'a':
  34.       case 'A':
  35.         or = (oread *)malloc(sizeof(oread));
  36.         or->fd = 0;
  37.         break;
  38.       case 'b':
  39.       case 'B':
  40.         or = (oread *)malloc(sizeof(oread));
  41.         or->fd = 1;
  42.         break;
  43.       default:
  44.         printf("Invalid drive specified: %s\n", fn);
  45.         return 0;
  46.     }
  47.     while ((status = biosdisk(D_READ, or->fd, 0, 0, 1, 1, buf)) == 6)
  48.       /* wait for valid read */ ;
  49.     if (status)
  50.       return 0;
  51.  
  52.     r.r_ax = 0x0800;
  53.     r.r_dx = or->fd;
  54.     intr(0x13, &r);
  55.     or->cm = (((r.r_cx & 0x00c0) << 2) | ((r.r_cx >> 8) & 0xff))+1;
  56.     or->hm = (r.r_dx >> 8)+1;
  57.     or->sm = r.r_cx & 0x3f;
  58.     or->file_ptr = 0L;
  59.     or->cache = (void *)malloc(512*CACHE_SECTORS);
  60.     or->cache_fptr = -512*CACHE_SECTORS;
  61.     or->cache_fptre = -512*CACHE_SECTORS;
  62.     or->volume_in_drive = 0;
  63.     return or;
  64.   }
  65.   else
  66.   {
  67.     int fd;
  68.     fd = _open(fn, O_RDONLY);
  69.     if (fd < 0)
  70.       return 0;
  71.     or = (oread *)malloc(sizeof(oread));
  72.     or->fd = fd;
  73.     or->cm = 0;
  74.     return or;
  75.   }
  76. }
  77.  
  78. void oread_read(void *rv, void *buffer)
  79. {
  80.   oread *r = (oread *)rv;
  81.   if (r->cm)
  82.   {
  83.     int c, h, s, v, sc;
  84.     if ((r->file_ptr >= r->cache_fptr) && (r->file_ptr < r->cache_fptre))
  85.     {
  86.       memcpy(buffer, (char *)(r->cache) + r->file_ptr - r->cache_fptr, 512);
  87.       r->file_ptr += 512;
  88.       return;
  89.     }
  90.     s = (unsigned long)(r->file_ptr) / 512;
  91.     h = s / r->sm;
  92.     c = h / r->hm;
  93.     v = c / r->cm;
  94.     s = s % r->sm;
  95.     h = h % r->hm;
  96.     c = c % r->cm;
  97.     if (v != r->volume_in_drive)
  98.     {
  99.       printf("Please insert volume %03d . . .", v);
  100.       fflush(stdout);
  101.       if (getch() == 3)
  102.       {
  103.         printf("^C\n");
  104.         exit(3);
  105.       }
  106.       printf("\n");
  107.       r->volume_in_drive = v;
  108.       r->cache_fptr = -512*CACHE_SECTORS;
  109.     }
  110.     sc = r->sm - s;
  111.     if (sc > CACHE_SECTORS)
  112.       sc = CACHE_SECTORS;
  113.     printf("v=%02d c=%02d h=%02d s=%02d n=%02d\r", v, c, h, s, sc);
  114.     fflush(stdout);
  115.     if (biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache))
  116.       biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache);
  117.     memcpy(buffer, r->cache, 512);
  118.     r->cache_fptr = r->file_ptr;
  119.     r->cache_fptre = r->cache_fptr + 512*sc;
  120.     r->file_ptr += 512;
  121.   }
  122.   else
  123.   {
  124.     if (_read(r->fd, buffer, 512) != 512)
  125.     {
  126.       printf("Unexpected end-of-file\n");
  127.       exit(1);
  128.     }
  129.   }
  130. }
  131.  
  132. void oread_skip(void *rv, long skip_bytes)
  133. {
  134.   oread *r = (oread *)rv;
  135.   if (r->cm)
  136.   {
  137.     r->file_ptr += skip_bytes;
  138.   }
  139.   else
  140.   {
  141.     lseek(r->fd, skip_bytes, 1);
  142.   }
  143. }
  144.  
  145. void oread_close(void *rv)
  146. {
  147.   oread *r = (oread *)rv;
  148.   if (r->cm == 0)
  149.     _close(r->fd);
  150.   else
  151.     free(r->cache);
  152.   free(r);
  153. }
  154.